#include <map>

#include "tactics.hpp"

namespace game {

namespace {

class rally_tactic : public tactic
{
public:
	rally_tactic() : tactic("Rally", "Restores 3 hitpoints")
	{}

	void apply(unit_ptr u) const {
		u->heal(3);
		u->get_commander().use_command();
	}

	bool can_use(const_unit_ptr u) const {
		return u->get_commander().commands_left() > 0 && u->hitpoints() < 10;
	}
private:
};

class refresh_tactic : public tactic
{
public:
	refresh_tactic() : tactic("Refresh", "Restores unit's movement")
	{}

	void apply(unit_ptr u) const {
		u->restore_movement();
		u->get_commander().use_command();
	}

	bool can_use(const_unit_ptr u) const {
		return u->get_commander().commands_left() > 0 && u->moves_left() < u->movement();
	}
private:
};

std::map<std::string, const_tactic_ptr> tactics_map;
}

void tactic::get_available_tactics(const unit& u, std::vector<const_tactic_ptr>& tactics)
{
	if(u.is_commander()) {
		return;
	}

	tactics.push_back(get("rally"));
	tactics.push_back(get("refresh"));
}

const_tactic_ptr tactic::create(const std::string& key)
{
	if(key == "rally") {
		return const_tactic_ptr(new rally_tactic);
	} else  if(key == "refresh") {
		return const_tactic_ptr(new refresh_tactic);
	} else {
		return const_tactic_ptr();
	}
}

const_tactic_ptr tactic::get(const std::string& key)
{
	const_tactic_ptr& t = tactics_map[key];
	if(t.get() == NULL) {
		t = create(key);
	}

	return t;
}

tactic::tactic(const std::string& description, const std::string& help_string) : description_(description), help_string_(help_string)
{
}

tactic::~tactic()
{
}

}
